package cn.iocoder.yudao.module.ao.controller.admin.patrol;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;

import cn.iocoder.yudao.module.ao.controller.admin.patrol.vo.*;
import cn.iocoder.yudao.module.ao.dal.dataobject.patrol.PatrolDO;
import cn.iocoder.yudao.module.ao.service.patrol.PatrolService;
import cn.iocoder.yudao.module.ao.dal.mysql.vocationalclassschedule.VocationalClassScheduleMapper;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;

@Tag(name = "管理后台 - 巡班违纪记录")
@RestController
@RequestMapping("/ao/patrol")
@Validated
public class PatrolController {

    @Resource
    private PatrolService patrolService;

    @Resource
    private VocationalClassScheduleMapper vocationalClassScheduleMapper;

    @Resource
    private AdminUserService adminUserService;

    @Resource
    private cn.iocoder.yudao.module.system.service.permission.PermissionService permissionService;

    @PostMapping("/create")
    @Operation(summary = "创建巡班违纪记录")
    @PreAuthorize("@ss.hasPermission('ao:patrol:create')")
    public CommonResult<Long> createPatrol(@Valid @RequestBody PatrolSaveReqVO createReqVO) {
        return success(patrolService.createPatrol(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新巡班违纪记录")
    @PreAuthorize("@ss.hasPermission('ao:patrol:update')")
    public CommonResult<Boolean> updatePatrol(@Valid @RequestBody PatrolSaveReqVO updateReqVO) {
        patrolService.updatePatrol(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除巡班违纪记录")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('ao:patrol:delete')")
    public CommonResult<Boolean> deletePatrol(@RequestParam("id") Long id) {
        patrolService.deletePatrol(id);
        return success(true);
    }

    @DeleteMapping("/delete-list")
    @Parameter(name = "ids", description = "编号", required = true)
    @Operation(summary = "批量删除巡班违纪记录")
                @PreAuthorize("@ss.hasPermission('ao:patrol:delete')")
    public CommonResult<Boolean> deletePatrolList(@RequestParam("ids") List<Long> ids) {
        patrolService.deletePatrolListByIds(ids);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得巡班违纪记录")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('ao:patrol:query')")
    public CommonResult<PatrolRespVO> getPatrol(@RequestParam("id") Long id) {
        PatrolDO patrol = patrolService.getPatrol(id);
        return success(BeanUtils.toBean(patrol, PatrolRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得巡班违纪记录分页")
    @PreAuthorize("@ss.hasPermission('ao:patrol:query')")
    public CommonResult<PageResult<PatrolRespVO>> getPatrolPage(@Valid PatrolPageReqVO pageReqVO) {
        // 权限控制:普通老师只能查看自己班级的数据
        applyTeacherClassFilter(pageReqVO);
        
        PageResult<PatrolDO> pageResult = patrolService.getPatrolPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, PatrolRespVO.class));
    }

    /**
     * 应用教师权限过滤器(普通老师权限控制)
     * 普通老师(角色ID=2)可以查看两种违纪记录:
     * 1. 自己授课时被记录的违纪(teacher_name匹配)
     * 2. 自己作为班主任的班级的违纪(通过class_teacher查找班级教室)
     */
    private void applyTeacherClassFilter(PatrolPageReqVO pageReqVO) {
        // 获取当前登录用户ID
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        if (userId == null) {
            return;
        }

        // 获取用户信息
        AdminUserDO user = adminUserService.getUser(userId);
        if (user == null) {
            return;
        }

        // 获取用户的角色列表
        Set<Long> roleIds = permissionService.getUserRoleIdListByUserId(userId);

        // 判断是否是普通老师(角色ID=160),且不是管理员(角色ID=1)
        boolean isTeacher = roleIds.contains(160L);
        boolean isAdmin = roleIds.contains(1L);

        if (isTeacher && !isAdmin) {
            String teacherName = user.getRemark();

            if (StrUtil.isNotBlank(teacherName)) {
                // 设置授课老师过滤条件 - 可以看到自己授课时的违纪记录
                pageReqVO.setCurrentTeacherName(teacherName);
                
                // 查询该老师作为班主任管理的班级的所有教室
                List<String> classrooms = vocationalClassScheduleMapper.selectClassroomsByTeacherName(teacherName);
                
                if (CollUtil.isNotEmpty(classrooms)) {
                    // 设置教室过滤条件 - 可以看到自己班级的违纪记录
                    pageReqVO.setClassrooms(classrooms);
                }
                // 注意: 即使没有找到教室,也不设置__NO_CLASSROOM__
                // 因为至少可以看到自己授课的违纪记录(通过teacherName过滤)
            } else {
                // 如果用户没有配置姓名,不允许查看任何数据
                pageReqVO.setCurrentTeacherName("__NO_TEACHER__");
                pageReqVO.setClassrooms(Collections.singletonList("__NO_CLASSROOM__"));
            }
        }
        // 管理员或其他角色不做限制,可以查看所有数据
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出巡班违纪记录 Excel")
    @PreAuthorize("@ss.hasPermission('ao:patrol:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportPatrolExcel(@Valid PatrolPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<PatrolDO> list = patrolService.getPatrolPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "巡班违纪记录.xls", "数据", PatrolRespVO.class,
                        BeanUtils.toBean(list, PatrolRespVO.class));
    }

    /**
     * 获取巡班违纪记录分页 - 排名专用(不应用权限过滤)
     * 用于违纪排名统计,所有用户(包括普通老师)都能看到全校完整的排名数据
     * 但普通老师仍然只能点击查看自己权限范围内班级的详情
     */
    @GetMapping("/page-for-ranking")
    @Operation(summary = "获得巡班违纪记录分页(排名专用,无权限过滤)")
    @PreAuthorize("@ss.hasPermission('ao:patrol:query')")
    public CommonResult<PageResult<PatrolRespVO>> getPatrolPageForRanking(@Valid PatrolPageReqVO pageReqVO) {
        // 注意: 此接口不调用 applyTeacherClassFilter(),所有用户都能看到全校数据
        // 仅用于排名统计,不包含敏感的违纪详情
        PageResult<PatrolDO> pageResult = patrolService.getPatrolPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, PatrolRespVO.class));
    }

}